package cn.maiyar.feign.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.Map.Entry;

/**
 * feign 传递Request header
 *
 * @author c.c
 */
@Slf4j
@Configuration
public class FeignRequestHeaderInterceptor implements RequestInterceptor {

    /***对指定header做特殊过滤*/
    private static final Map<String, String> FILTER_HEADERS = new HashMap<>();

    static {
        FILTER_HEADERS.put("accept", "application/json");
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        HttpServletRequest request = getHttpServletRequest();
        if(request != null){
            Map<String, String> headers = getHeaders(request);
            filterHeaders(headers);
            if (headers.size() > 0) {
                for (Entry<String, String> entry : headers.entrySet()) {
                    // 把请求过来的header请求头 原样设置到feign请求头中
                    requestTemplate.header(entry.getKey(), entry.getValue());
                }
            }
        }
    }


    /***
     * 对指定header做修改操作
     * @param headers
     */
    private void filterHeaders(Map<String, String> headers) {
        if(headers == null || headers.isEmpty()){
            return;
        }

        Set<Entry<String, String>> filterHeaders = FILTER_HEADERS.entrySet();
        for(Entry<String, String> filterHeader : filterHeaders){
           if(headers.containsKey(filterHeader.getKey())){
               headers.put(filterHeader.getKey(), filterHeader.getValue());
           }
        }
    }

    private HttpServletRequest getHttpServletRequest() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (!ObjectUtils.isEmpty(attributes)) {
                return attributes.getRequest();
            }
            return null;
        } catch (Exception e) {
            log.error("feign拦截器中获取HttpServletRequest error:{}", e);
            return null;
        }
    }

    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enums = request.getHeaderNames();
        while (enums.hasMoreElements()) {
            String key = enums.nextElement();
            String value = request.getHeader(key);
            map.put(key, value);
        }
        return map;
    }
}
